﻿namespace LM.Servicos
{
    using System;
    using LM.InterfacesFabricas.DTOs;
    using LM.InterfacesFabricas.Interfaces.Servicos;
    using LM.InterfacesFabricas.Utilidades;
    using LM.Negocio.Objetos;
    using LM.Negocio.Validadores;
    using LM.InterfacesFabricas.Fabricas;
    using System.Collections.Generic;
    using iTextSharp.text;
    using iTextSharp.text.pdf;
    using System.IO;
    using System.Linq;
    using LM.InterfacesFabricas.Basicos.Enumeradores;

    /// <summary>
    /// Rafael.
    /// Fornece Operações para a Manipulação de Relatórios.
    /// </summary>
    public class ServicoDeRelatorios : IServicoDeRelatorios
    {
        private ValidadorDeRelatorio _validador;

        public ServicoDeRelatorios() 
        {
            _validador = new ValidadorDeRelatorio();
        }

        #region IServicoDeRelatorios Members

        public void ImprimeRelatorioPorPeriodo(DateTime dataInicial, DateTime dataFinal)
        {
            _validador.ValideRelatorioPorPeriodo(dataInicial, dataFinal);

            var servicoDeLocacao = FabricaGenerica.Crie<IServicoDeLocacao>();

            var listaDeLocacoes = servicoDeLocacao.ConsulteLocacoesPorPeriodo(dataInicial, dataFinal);
            
            if (listaDeLocacoes.Count > 0)
            {
                ImprimeRelatorioDeLocacoes(listaDeLocacoes);
            } 
        }

        public void ImprimeRelatorioPorCliente(DtoCliente dtoCliente)
        {
            var cliente = ConversorDeObjetos.Copie<Cliente>(dtoCliente);

            _validador.ValideRelatorioPorCliente(cliente);

            var servicoDeLocacao = FabricaGenerica.Crie<IServicoDeLocacao>();

            var listaDeLocacoes = servicoDeLocacao.ConsultePeloCliente(dtoCliente.Nome);

            if (listaDeLocacoes.Count > 0)
            {
                CriaRelatorio(GeraRelatorioLocacaoPorCliente(listaDeLocacoes));
            }
        }

        #endregion

        private List<string> GeraRelatorioLocacao(DtoLocacao locacao)
        {
            var documento = new List<string>();

            documento.Add(String.Format("Código: {0} ", locacao.Cliente.Codigo));
            documento.Add(String.Format("Nome: {0}  Cpf: {1} ", locacao.Cliente.Nome, locacao.Cliente.Cpf));
            documento.Add(String.Format("Telefone: {0}", "("+locacao.Cliente.Telefones.FirstOrDefault().Ddd + ") "
                + " " + locacao.Cliente.Telefones.FirstOrDefault().Numero));

            string dadosLocacao = String.Format("Data de Entrada: {0,10:dd/MM/yyyy} Data de Saida: {1,10:dd/MM/yyyy} Desconto: {2,5} Total: {3,5:C}",
                    locacao.DataEntrada,
                    locacao.DataSaida,
                    locacao.Desconto,
                    locacao.Total);

            documento.Add(dadosLocacao);

            return documento;
        }

        private List<string> GeraRelatorioLocacaoPorCliente(IList<DtoLocacao> locacoes) 
        {
            //dados do Cliente
            var cliente = locacoes.FirstOrDefault().Cliente;
            var documento = new List<string>();
            documento.Add(String.Format("Código: {0,20} ", cliente.Codigo));
            documento.Add(String.Format("Nome: {0,200} Cpf: {1, 20} ", cliente.Nome, cliente.Cpf));
            documento.Add(String.Format("Telefone: {0,20:(00) 0000-0000}", cliente.Telefones.FirstOrDefault().Ddd
                + " " + cliente.Telefones.FirstOrDefault().Numero));

            //locações do Cliente
            foreach (var locacao in locacoes)
            {
                string tabelaDeLocacoes = String.Format("{1,15:ddMMyyyy}{1,15:ddMMyyyy}{2,20}{3,20:C}",
                        locacao.DataEntrada,
                        locacao.DataSaida,
                        locacao.Desconto,
                        locacao.Total);

                documento.Add(tabelaDeLocacoes);
            }

            //fazer uma expressão link para calcular
            string totalGasto = "";

            documento.Add(String.Format("Total Gasto: {0}", totalGasto));
            
            return documento;
        }

        private void CriaRelatorio(List<string> relatorio)
        {
            // cria uma instância de iTextSharp.text.Document
            Document documento = new Document();

            // cria um Writer para o documento
            PdfWriter.GetInstance(documento, new
              FileStream("C:\\Relatorio.pdf", FileMode.Create));

            // abre o documento
            documento.Open();

            foreach (var linha in relatorio)
            {
                documento.Add(new Paragraph(linha));
            }

            //dados finais do relatório

            //rodapé

            // fecha o documento
            documento.Close();

            // manda abrir o aquivo criado
            System.Diagnostics.Process.Start(@"C:\Relatorio.pdf");
        }

        public void ImprimeRelatorioDeLocacoes(IList<DtoLocacao> locacoes)
        {
            // cria uma instância de iTextSharp.text.Document
            Document documento = new Document();

            // cria um Writer para o documento
            PdfWriter.GetInstance(documento, new
              FileStream("C:\\Relatorio.pdf", FileMode.Create));

            // abre o documento
            documento.Open();

            foreach (var locacao in locacoes)
            {
                foreach (var item in GeraRelatorioLocacao(locacao))
                {
                    documento.Add(new Paragraph(item));
                }
            }

            //dados finais do relatório

            //rodapé

            // fecha o documento
            documento.Close();

            // manda abrir o aquivo criado
            System.Diagnostics.Process.Start(@"C:\Relatorio.pdf"); 
        }
    }
}
